Menampilkan Gambar

Package dasar EBImage memiliki fungsi yaitu membaca, menulis, dan menampilkan gambar. EBImage membaca gambar dengan menggunakan function readImage() dimana dalam function tersebut nantinya dimasukkan url gambar yang ingin ditampilkan.

Package EBImage saat ini mendukung 3 jenis format gambar, yaitu jpg, png, dan tiff.

library("EBImage")
img <- readImage('dandelion.jpg')
# Menampilkan gambar di penampil JavaScript pada tab browser web
display(img, method="browser")
# Menampilkan gambar seperti biasa tetapi dengan tambahan label di atasnya
display(img, method="raster")
text(x = 20, y = 20, label = "Dandelion", adj = c(0,1), col = "white", cex = 2)

# Menyimpan gambar di perangkat R 
filename = "bungasinga.jpg"
dev.print(jpeg, filename = filename , width = dim(img)[1], height = dim(img)[2])
## png 
##   2
file.info(filename)$size
## [1] 41530
imgcol <- readImage('tiger-color.jpg')
display(imgcol)

Representasi Data Gambar

Memperlihatkan struktur internal obyek gambar

str(img)
## Formal class 'Image' [package "EBImage"] with 2 slots
##   ..@ .Data    : num [1:960, 1:503, 1:3] 0.42 0.424 0.427 0.427 0.427 ...
##   ..@ colormode: int 2
dim(img)
## [1] 960 503   3
imageData(img)[1:3, 1:6]
## Error in imageData(img)[1:3, 1:6]: incorrect number of dimensions
is.Image( as.array(img) )
## [1] FALSE
hist(img)

range(img)
## [1] 0 1
img
## Image 
##   colorMode    : Color 
##   storage.mode : double 
##   dim          : 960 503 3 
##   frames.total : 3 
##   frames.render: 1 
## 
## imageData(object)[1:5,1:6,1]
##           [,1]      [,2]      [,3]     [,4]     [,5]     [,6]
## [1,] 0.4196078 0.4235294 0.4235294 0.427451 0.427451 0.427451
## [2,] 0.4235294 0.4235294 0.4274510 0.427451 0.427451 0.427451
## [3,] 0.4274510 0.4274510 0.4274510 0.427451 0.427451 0.427451
## [4,] 0.4274510 0.4274510 0.4313725 0.427451 0.427451 0.427451
## [5,] 0.4274510 0.4274510 0.4313725 0.427451 0.427451 0.427451
print(img, short=TRUE)
## Image 
##   colorMode    : Color 
##   storage.mode : double 
##   dim          : 960 503 3 
##   frames.total : 3 
##   frames.render: 1
print(imgcol, short=TRUE)
## Image 
##   colorMode    : Color 
##   storage.mode : double 
##   dim          : 512 307 3 
##   frames.total : 3 
##   frames.render: 1
numberOfFrames(imgcol, type = "render")
## [1] 1
numberOfFrames(imgcol, type = "total")
## [1] 3
nuc
## Error in eval(expr, envir, enclos): object 'nuc' not found

Pengelolaan Warna

Fungsi colorMode adalah untuk mengakses dan mengubah mode rendering gambar. Misalnya, mengubah skala warna gambar menjadi abu-abu maka gambar akan ditampilkan tidak berwarna lagi, melainkan ditampilkan abu-abu

colorMode(imgcol) = Grayscale
display(imgcol, all=TRUE)

colorMat = matrix(rep(c("red","green", "#0000ff"), 25), 5, 5)
colorImg = Image(colorMat)
colorImg
## Image 
##   colorMode    : Color 
##   storage.mode : double 
##   dim          : 5 5 3 
##   frames.total : 3 
##   frames.render: 1 
## 
## imageData(object)[1:5,1:5,1]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    1    0
## [2,]    0    1    0    0    1
## [3,]    0    0    1    0    0
## [4,]    1    0    0    1    0
## [5,]    0    1    0    0    1
display(colorImg, interpolate=FALSE)

Memanipulasi Gambar

Memanipulasi gambar dengan operator aritmatika R. Misalnya, kita dapat mengurangkan gambar dari nilai maksimumnya sehingga menghasilkan gambar negatif

img_neg = max(img) - img
display( img_neg )

img_comb = combine(
  img,
  img + 0.3,
  img * 2,
  img ^ 0.5
)

img_t = transpose(img)
display( img_t )

Transformasi Spasial

Transformasi spasial digunakan untuk mengubah posisi gambar, dimana beberapa contohnya adalah translasi, rotasi, refleksi, dan penskalaan

img_translate = translate(img, c(100,-50))
display(img_translate)

img_rotate = rotate(img, 30, bg.col = "white")
display(img_rotate)

img_resize = resize(img, w=256, h=256)
display(img_resize )

img_flip = flip(img)
img_flop = flop(img)
display(combine(img_flip, img_flop), all=TRUE)

m =  matrix(c(1, -.5, 128, 0, 1, 0), nrow=3, ncol=2)
img_affine = affine(img, m)
display( img_affine )

Filter Gambar

# Linear Filters
w = makeBrush(size = 31, shape = 'gaussian', sigma = 5)
plot(w[(nrow(w)+1)/2, ], ylab = "w", xlab = "", cex = 0.7)

img_flo = filter2(img, w)
display(img_flo)

nuc_gblur = gblur(nuc, sigma = 5)
## Error in validObject(x): object 'nuc' not found
display(nuc_gblur, all=TRUE )
## Error in validImageObject(x): object 'nuc_gblur' not found
fhi = matrix(1, nrow = 3, ncol = 3)
fhi[2, 2] = -8
img_fhi = filter2(img, fhi)
display(img_fhi)

# Median Filters
l = length(img)
n = l/10
pixels = sample(l, n)
img_noisy = img
img_noisy[pixels] = runif(n, min=0, max=1)
display(img_noisy)

img_median = medianFilter(img_noisy, 1)
display(img_median)

Morphological operations

shapes = readImage(system.file('images', 'shapes.png', package='EBImage'))
logo = shapes[110:512,1:130]
display(logo)

kern = makeBrush(3, shape='diamond')
display(kern, interpolate=FALSE)

logo_erode= erode(logo, kern)
logo_dilate = dilate(logo, kern)
display(combine(logo_erode, logo_dilate), all=TRUE)

Fourier Transform

# FFT Shift Transform
fftshift <- function(img_ff, dim = -1) {

  rows <- dim(img_ff)[1]    
  cols <- dim(img_ff)[2]
  # planes <- dim(img_ff)[3]

  swap_up_down <- function(img_ff) {
    rows_half <- ceiling(rows/2)
    return(rbind(img_ff[((rows_half+1):rows), (1:cols)], img_ff[(1:rows_half), (1:cols)]))
  }

  swap_left_right <- function(img_ff) {
    cols_half <- ceiling(cols/2)
    return(cbind(img_ff[1:rows, ((cols_half+1):cols)], img_ff[1:rows, 1:cols_half]))
  }
  
  if (dim == -1) {
    img_ff <- swap_up_down(img_ff)
    return(swap_left_right(img_ff))
  }
  else if (dim == 1) {
    return(swap_up_down(img_ff))
  }
  else if (dim == 2) {
    return(swap_left_right(img_ff))
  }
  else if (dim == 3) {
  # Menggunakan package 'abind'
  # install.packages("abind")
    library(abind)
    
    planes <- dim(img_ff)[3]
    rows_half <- ceiling(rows/2)
    cols_half <- ceiling(cols/2)
    planes_half <- ceiling(planes/2)
    
    img_ff <- abind(img_ff[((rows_half+1):rows), (1:cols), (1:planes)], 
                    img_ff[(1:rows_half), (1:cols), (1:planes)], along=1)
    img_ff <- abind(img_ff[1:rows, ((cols_half+1):cols), (1:planes)], 
                    img_ff[1:rows, 1:cols_half, (1:planes)], along=2)
    img_ff <- abind(img_ff[1:rows, 1:cols, ((planes_half+1):planes)], 
                    img_ff[1:rows, 1:cols, 1:planes_half], along=3)
    return(img_ff)
  }
  else {
    stop("Invalid dimension parameter")
  }
}
str(img)
## Formal class 'Image' [package "EBImage"] with 2 slots
##   ..@ .Data    : num [1:960, 1:503, 1:3] 0.42 0.424 0.427 0.427 0.427 ...
##   ..@ colormode: int 2
imgMat <- matrix(img, nrow = dim(img)[1], ncol = dim(img)[2])
dim(imgMat)
## [1] 960 503
# FT
ft_imgMat <- fft(imgMat)  
display(fftshift(ft_imgMat))
## Warning in storage.mode(x) <- "double": imaginary parts discarded in coercion

# Besaran dan Fase
mag_ft_imgMat <- sqrt(Re(ft_imgMat)^2+Im(ft_imgMat)^2)
display(mag_ft_imgMat)

phase_ft_imgMat  <- atan2(Im(ft_imgMat), Re(ft_imgMat))

EBImage::display(log(fftshift(ft_imgMat)), title="FT Magnitude (Cyrillic Alphabet)")
## Warning in storage.mode(x) <- "double": imaginary parts discarded in coercion

Rekonstruksi IFT

Real = mag_ft_imgMat * cos(phase_ft_imgMat)
Imaginary = mag_ft_imgMat * sin(phase_ft_imgMat)
ift_ft_imgMat = Re(fft(Real+1i*Imaginary, inverse = T)/length(mag_ft_imgMat))
EBImage::display(ift_ft_imgMat, method = "raster", title="(IFT o FT) Magnitude=Img | Phase=Img")

# Pemfilteran Frekuensi Low-pass
mag_ft_imgMat_1 <- mag_ft_imgMat
for (i in 1:dim(mag_ft_imgMat)[1]) {
  for (j in 1:dim(mag_ft_imgMat)[2]) {
    if (abs(i-(dim(mag_ft_imgMat)[1])/2) > (dim(mag_ft_imgMat)[1])/4 | 
        abs(j-(dim(mag_ft_imgMat)[2])/2) > (dim(mag_ft_imgMat)[2])/4) {
      mag_ft_imgMat_1[i,j] <- 0
    }
  }
}

EBImage::display(mag_ft_imgMat_1, method = "raster", title="(IFT o LowPassFilter o FT) Magnitude=Img | Phase=Img")

Real = mag_ft_imgMat_1 * cos(phase_ft_imgMat)
Imaginary = mag_ft_imgMat_1 * sin(phase_ft_imgMat)
ift_ft_imgMat_1 = Re(fft(Real+1i*Imaginary, inverse = T)/length(mag_ft_imgMat_1))
EBImage::display(100*ift_ft_imgMat_1, method = "raster", title="(IFT o LowPassFilter o FT) Magnitude=Img | Phase=Img")

# Pemfilteran Frekuensi High-pass
mag_ft_imgMat_2 <- mag_ft_imgMat
for (i in 1:dim(mag_ft_imgMat)[1]) {
  for (j in 1:dim(mag_ft_imgMat)[2]) {
    if (abs(i-(dim(mag_ft_imgMat)[1])/2) < (dim(mag_ft_imgMat)[1])/4 & 
        abs(j-(dim(mag_ft_imgMat)[2])/2) < (dim(mag_ft_imgMat)[2])/4) {
      mag_ft_imgMat_2[i,j] <- 0
    }
  }
}

EBImage::display(mag_ft_imgMat_2, method = "raster", title="(IFT o HighPassFilter o FT) Magnitude=Img | Phase=Img")

Real = mag_ft_imgMat_2 * cos(phase_ft_imgMat)
Imaginary = mag_ft_imgMat_2 * sin(phase_ft_imgMat)
ift_ft_imgMat_2 = Re(fft(Real+1i*Imaginary, inverse = T)/length(mag_ft_imgMat_2))
EBImage::display(ift_ft_imgMat_2, method = "raster", title="(IFT o HighPassFilter o FT) Magnitude=Img | Phase=Img")

Segmentasi Gambar

Segmentasi gambar melakukan partisi gambar, dan biasanya digunakan untuk mengidentifikasi objek dalam gambar

logo_label = bwlabel(logo)
table(logo_label)
## logo_label
##     0     1     2     3     4     5     6     7 
## 42217  1375  2012   934  1957  1135  1697  1063
max(logo_label)
## [1] 7
display( normalize(logo_label) )

display( colorLabels(logo_label) )

Manipulasi Objek

# Penghapusan Objek
objects = list(
    seq.int(from = 2, to = max(logo_label), by = 2),
    seq.int(from = 1, to = max(logo_label), by = 2)
    )
logos = combine(logo_label, logo_label)
z = rmObjects(logos, objects, reenumerate=FALSE)
display(z, all=TRUE)

showIds = function(image) lapply(getFrames(image), function(frame) unique(as.vector(frame)))

showIds(z)
## [[1]]
## [1] 0 1 3 5 7
## 
## [[2]]
## [1] 0 2 4 6
showIds( reenumerate(z) )
## [[1]]
## [1] 0 1 2 3 4
## 
## [[2]]
## [1] 0 1 2 3
# Pengisian Lubang dan Daerah Objek
filled_logo = fillHull(logo)
display(filled_logo)

rgblogo = toRGB(logo)
points = rbind(c(50, 50), c(100, 50), c(150, 50))
colors = c("red", "green", "blue")
rgblogo = floodFill(rgblogo, points, colors)
display( rgblogo )

display(floodFill(img, rbind(c(200, 300), c(444, 222)), col=0.2, tolerance=0.2))

# Penyorotan Objek
d1 = dim(img)[1:2]
overlay = Image(dim=d1)
d2 = dim(logo_label)-1

offset = (d1-d2) %/% 2

overlay[offset[1]:(offset[1]+d2[1]), offset[2]:(offset[2]+d2[2])] = logo_label

img_logo = paintObjects(overlay, toRGB(img), col=c("red", "white"), opac=c(1, 0.3), thick=TRUE)

display( img_logo )

Contoh Segmentasi Sel

nuc = readImage(system.file('images', 'nuclei.tif', package='EBImage'))
cel = readImage(system.file('images', 'cells.tif', package='EBImage'))

cells = rgbImage(green=1.5*cel, blue=nuc)
display(cells, all = TRUE)

nmask = thresh(nuc, w=10, h=10, offset=0.05)
nmask = opening(nmask, makeBrush(5, shape='disc'))
nmask = fillHull(nmask)
nmask = bwlabel(nmask)

display(nmask, all=TRUE)

ctmask = opening(cel>0.1, makeBrush(5, shape='disc'))
cmask = propagate(cel, seeds=nmask, mask=ctmask)

display(ctmask, all=TRUE)

segmented = paintObjects(cmask, cells, col='#ff00ff')
segmented = paintObjects(nmask, segmented, col='#ffff00')

display(segmented, all=TRUE)

Sumber Referensi : http://www.socr.umich.edu/people/dinov/courses/DSPA_notes/DSPA_Appendix_6_ImageFilteringSpectralProcessing.html#113_Highlighting_objects